/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "vec_array.h"

#include <omp.h>
#include "core/结构数据.h"
#include "core/vec_conversion.h"



//S_F32Array* f_f32_array_alloc() {
//	return (S_F32Array*)f_core_array_new(0, sizeof(float32));
//}

void f_f32_array_free(S_F32Array* a) {

}

S_Vec3Array* f_vec3_array_alloc(uint64 num) {
	return (S_Vec3Array*)f_core_array_new(num, sizeof(vec3));
}

void f_vec3_array_free(S_Vec3Array* a) {
	f_core_array_free((S_Array*)a);
}

S_F32Array* f_f32_array_过度函数_从CXX_alloc(void* data) {
	auto& verts = *((std::vector<float32>*)data);
	uint32 num = verts.size();

	S_F32Array* v = (S_F32Array*)f_core_array_new(num, sizeof(float32));

	for (uint32 i = 0; i < num; ++i) {
		v->ptr_userData[i] = verts[i];
	}

	return v;
}

S_F32Array* f_f32_array_fromF32_alloc(float32 data) {
	S_F32Array* v = (S_F32Array*)f_core_array_new(1, sizeof(float32));
	v->ptr_userData[0] = data;
	return v;
}

S_F32Array* f_f32_array_fromI32_alloc(S_I32Array* data) {
	uint32 num = data->count;
	S_F32Array* v = (S_F32Array*)f_core_array_new(num, sizeof(float32));
	for (uint32 i = 0; i < num; ++i) {
		v->ptr_userData[i] = data->ptr_userData[i];
	}
	return v;
}

S_Vec2Array* f_vec2_array_fromV_alloc(float32* data) {
	S_Vec2Array* v = (S_Vec2Array*)f_core_array_new(1, sizeof(vec2));
	v->ptr_userData[0] = {data[0], data[0]};
	return v;
}

S_Vec2Array* f_vec2_array_from_alloc(S_F32Array* data) {
	uint32 num = data->count;
	S_Vec2Array* v = (S_Vec2Array*)f_core_array_new(num, sizeof(vec2));
	for (uint32 i = 0; i < num; ++i) {
		float32 t = data->ptr_userData[i];
		v->ptr_userData[i] = { t, t };
	}
	return v;
}

S_Vec2Array* f_vec2_array_fromV3s_alloc(S_Vec3Array* data) {
	uint32 num = data->count;
	S_Vec2Array* v = (S_Vec2Array*)f_core_array_new(num, sizeof(vec2));
	for (uint32 i = 0; i < num; ++i) {
		vec3 t = data->ptr_userData[i];
		v->ptr_userData[i] = { t.x, t.y };
	}
	return v;
}

S_Vec3Array* f_vec3_array_过度函数_从CXX_alloc(void* data) {
	auto& verts = *((std::vector<vec3>*)data);
	uint32 num = verts.size();

	S_Vec3Array* v = (S_Vec3Array*)f_core_array_new(num, sizeof(vec3));

	for (uint32 i = 0; i < num; ++i) {
		v->ptr_userData[i] = verts[i];
	}

	return v;
}

S_Vec3Array* f_vec3_array_fromV3_alloc(vec3 data) {
	S_Vec3Array* v = (S_Vec3Array*)f_core_array_new(1, sizeof(vec3));
	v->ptr_userData[0] = { data.x, data.y, data.z };
	return v;
}

S_Vec3Array* f_vec3_array_fromV4_alloc(vec4 data) {
	S_Vec3Array* v = (S_Vec3Array*)f_core_array_new(1, sizeof(vec3));
	v->ptr_userData[0] = { data.x, data.y, data.z };
	return v;
}

S_Vec4Array* f_vec4_array_fromV3_alloc(vec3 data) {
	S_Vec4Array* v = (S_Vec4Array*)f_core_array_new(1, sizeof(vec4));
	v->ptr_userData[0] = { data.x, data.y, data.z, 0 };
	return v;
}
S_Vec4Array* f_vec4_array_fromV4_alloc(vec4 data) {
	S_Vec4Array* v = (S_Vec4Array*)f_core_array_new(1, sizeof(vec4));
	v->ptr_userData[0] = { data.x, data.y, data.z, data.w };
	return v;
}
S_Vec4Array* f_vec4_array_fromV3s_alloc(S_Vec3Array* data) {
	uint32 num = data->count;
	S_Vec4Array* v = (S_Vec4Array*)f_core_array_new(num, sizeof(vec4));
	for (uint32 i = 0; i < num; ++i) {
		vec3 t = data->ptr_userData[i];
		vec4 v4 = { t.x, t.y, t.z, 0 };
		v->ptr_userData[i] = v4;
	}
	return v;
}

Mat44f f_Mat44_array_formMat44Array(S_Mat44Array* mats) {
	Mat44f mat = f_mat44_identity();
	if (mats->count) {
		mat = mats->ptr_userData[0];
	}
	return mat;
}

S_Mat44Array* f_Mat44_array_fromMat44_alloc(const Mat44f& data) {
	S_Mat44Array* v = (S_Mat44Array*)f_core_array_new(1, sizeof(Mat44f));
	v->ptr_userData[0] = data;
	return v;
}

S_Mat44Array* f_Mat44_array_fromMat44_alloc_过度函数(void* data) {
	auto& mat = *((std::vector<Mat44f>*)data);
	uint32 num = mat.size();
	S_Mat44Array* v = (S_Mat44Array*)f_core_array_new(num, sizeof(Mat44f));
	for (uint32 i = 0; i < num; ++i) {
		v->ptr_userData[i] = mat[i];
	}
	return v;
}

S_边Array* f_Edge1D_array_fromEdge_alloc(S_边* data) {

	return nullptr;
}

void f_f32_array_步进(S_F32Array* a, const vec2& r) {
	float32 s = (r.y - r.x) / a->count;

	for (uint32 i = 0; i < a->count; ++i) {
		a->ptr_userData[i] = s * i + r.x;
	}
}

void f_f32_array_随机(S_F32Array* a, const vec2& r, bool 覆盖) {

}




S_ElementSelect* f_array_元素选择_alloc() {
	S_ElementSelect* ElementSelect = (S_ElementSelect*)malloc(sizeof(S_ElementSelect));
	ElementSelect->Index = (S_UI32Array*)f_core_array_new(0, sizeof(uint32));
	ElementSelect->Element = nullptr;
	ElementSelect->Type = E_值类型::e_Type_None;
	return ElementSelect;
}

S_ElementSelectArray* f_array_元素选择数组_alloc() {
	S_ElementSelectArray* array = (S_ElementSelectArray*)f_core_array_new(0, sizeof(S_ElementSelect*));
	//S_ElementSelectArray* array = (S_ElementSelectArray*)malloc(sizeof(S_ElementSelectArray));
	return array;
}

void f_array_元素选择数组_resize(S_ElementSelectArray* es, uint32 num) {
	uint32 begin = es->count;
	for (uint32 i = num; i < es->count; ++i) {
		f_core_array_free((S_Array*)es->ptr_userData[i]->Index);
	}
	f_core_array_resize((S_Array*)es, num);

	for (uint32 i = begin; i < es->count; ++i) {
		es->ptr_userData[i] = f_array_元素选择_alloc();
	}
}




void f_vec_取矢量分量(const S_Vec3Array* 矢量, const S_I8Array* 索引, S_F32Array* 分量, const S_Props& m_分量类型) {
	uint32 num = DEF_Max(矢量->count, 索引->count);
	


	uint32 v1Num;
	uint32 v2Num;
	uint32* 索引1 = f_array_多例索引((S_Array*)矢量, v1Num);
	uint32* 索引2 = f_array_多例索引((S_Array*)索引, v2Num);


	bool 矢量多例 = 矢量->count >= num;
	bool 索引多例 = 索引->count >= num;
	switch (f_prop_enum(m_分量类型)) {
		case 0: {
			//num = DEF_Max(索引1 ? v1Num : num, 索引2 ? v2Num : num);
			if (索引1 || 索引2) {
				if (索引1) {
					num = v1Num;
				}
				else if (索引2) {
					num = v2Num;
				}
				f_core_array_resize((S_Array*)分量, num);

				矢量多例 = v1Num >= num;
				索引多例 = v2Num >= num;

				for (uint32 i = 0; i < num; ++i) {
					vec3 v;
					if (索引1) {
						v = 矢量多例 ? 矢量->ptr_userData[索引1[i]] : 矢量->ptr_userData[索引1[0]];
					}
					else {
						v = 矢量多例 ? 矢量->ptr_userData[i] : 矢量->ptr_userData[0];
					}

					uint8 index;
					if (索引2) {
						index = 索引多例 ? 索引->ptr_userData[索引2[i]] : 索引->ptr_userData[索引2[0]];
					}
					else {
						index = 索引多例 ? 索引->ptr_userData[i] : 索引->ptr_userData[0];
					}
					index = clamp(index, 0, 2);

					分量->ptr_userData[i] = ((float32*)&(v))[index];
				}
			}
			else {
				f_core_array_resize((S_Array*)分量, num);

				for (uint32 i = 0; i < num; ++i) {
					vec3 v = 矢量多例 ? 矢量->ptr_userData[i] : 矢量->ptr_userData[0];

					uint8 index = 索引多例 ? 索引->ptr_userData[i] : 索引->ptr_userData[0];
					index = clamp(index, 0, 2);
					
					分量->ptr_userData[i] = ((float32*)&(v))[index];
					//分量->ptr_userData[i] = 矢量多例 ? ((float32*)&(v))[index] : ((float32*)&(v))[index];
				}
			}
			break;
		}
		case 1: {
			if (索引1) {
				num = v1Num;
				索引多例 = 索引->count >= num;
				f_core_array_resize((S_Array*)分量, num);

				for (uint32 i = 0; i < num; ++i) {
					vec3 v = 矢量->ptr_userData[索引1[i]];

					float32 a = DEF_Max(v.x, v.y);
					分量->ptr_userData[i] = DEF_Max(v.z, a);
				}
			}
			else {
				f_core_array_resize((S_Array*)分量, num);

				for (uint32 i = 0; i < num; ++i) {
					vec3 v = 矢量多例 ? 矢量->ptr_userData[i] : 矢量->ptr_userData[0];
					float32 a = DEF_Max(v.x, v.y);
					分量->ptr_userData[i] = DEF_Max(v.z, a);
				}
			}
			
			break;
		}
		case 2: {
			if (索引1) {
				num = v1Num;
				索引多例 = 索引->count >= num;
				f_core_array_resize((S_Array*)分量, num);

				for (uint32 i = 0; i < num; ++i) {
					vec3 v = 矢量->ptr_userData[索引1[i]];

					float32 a = DEF_Max(v.x, v.y);
					分量->ptr_userData[i] = DEF_Max(v.z, a);
				}
			}
			else {
				f_core_array_resize((S_Array*)分量, num);

				for (uint32 i = 0; i < num; ++i) {
					vec3 v = 矢量多例 ? 矢量->ptr_userData[i] : 矢量->ptr_userData[0];
					float32 a = DEF_Min(v.x, v.y);
					分量->ptr_userData[i] = DEF_Min(v.z, a);
				}
			}
			break;
		}
		default:
			break;
	}
}




void f_omp_set_num_threads(uint32 循环次数, const S_Props& 线程数量) {
	const int32 tn = f_prop_I32(线程数量);
	if (tn <= 0) {
		omp_set_num_threads(循环次数);
	}
	else {
		omp_set_num_threads(tn);
	}
}

void f_omp_set_threadsNum(uint32 线程数量) {
	omp_set_num_threads(线程数量);
}





